from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime

from ..database import get_db
from ..models.models import Student, Room, Building, Gender
from ..schemas import (
    RoomResponse, BuildingResponse,
    RoomAssignmentRequest, SwapRequestCreate,
    SwapRequestResponse, BuildingStatsResponse,
    RoomOccupancyResponse, RoomStatsResponse
)
from ..services.dormitory_assignment import DormitoryAssignmentService
from .auth import get_current_user, get_current_admin

router = APIRouter(
    prefix="/dormitory",
    tags=["宿舍管理"]
)

@router.get("/buildings", response_model=List[BuildingResponse])
async def list_buildings(
    gender: Optional[Gender] = None,
    db: Session = Depends(get_db)
):
    """
    获取所有宿舍楼信息
    
    参数:
    - gender: 可选，按性别筛选
    """
    query = db.query(Building)
    if gender:
        query = query.filter(Building.gender == gender)
    return query.all()

@router.get("/buildings/{building_id}", response_model=BuildingStatsResponse)
async def get_building_stats(
    building_id: int,
    db: Session = Depends(get_db)
):
    """
    获取宿舍楼统计信息
    
    参数:
    - building_id: 楼栋ID
    """
    dormitory_service = DormitoryAssignmentService(db)
    return dormitory_service.get_building_statistics(building_id)

@router.get("/rooms", response_model=List[RoomResponse])
async def list_available_rooms(
    building_id: Optional[int] = None,
    floor: Optional[int] = None,
    gender: Optional[Gender] = None,
    min_beds: Optional[int] = Query(None, ge=1),
    db: Session = Depends(get_db)
):
    """
    查询可用宿舍
    
    参数:
    - building_id: 可选，楼栋ID
    - floor: 可选，楼层
    - gender: 可选，性别要求
    - min_beds: 可选，最少需要的床位数
    """
    dormitory_service = DormitoryAssignmentService(db)
    if gender:
        rooms = dormitory_service.get_available_rooms(
            gender=gender,
            required_capacity=min_beds or 1,
            preferred_floor=floor,
            preferred_building=building_id
        )
    else:
        # 如果没有指定性别，则查询所有房间
        query = db.query(Room).join(Building)
        if building_id:
            query = query.filter(Room.building_id == building_id)
        if floor:
            query = query.filter(Room.floor == floor)
        if min_beds:
            query = query.filter(Room.capacity - Room.current_occupancy >= min_beds)
        rooms = query.all()
    
    return rooms

@router.get("/rooms/{room_id}", response_model=RoomStatsResponse)
async def get_room_detail(
    room_id: int,
    db: Session = Depends(get_db)
):
    """
    获取宿舍详细信息
    
    参数:
    - room_id: 房间ID
    """
    dormitory_service = DormitoryAssignmentService(db)
    return dormitory_service.get_room_statistics(room_id)

@router.get("/rooms/{room_id}/occupants", response_model=RoomOccupancyResponse)
async def get_room_occupants(
    room_id: int,
    db: Session = Depends(get_db)
):
    """
    获取宿舍入住情况
    
    参数:
    - room_id: 房间ID
    """
    dormitory_service = DormitoryAssignmentService(db)
    room = db.query(Room).get(room_id)
    if not room:
        raise HTTPException(status_code=404, detail="房间不存在")
        
    occupants = dormitory_service.get_room_occupants(room_id)
    
    return {
        "room_id": room_id,
        "room_number": room.room_number,
        "capacity": room.capacity,
        "current_num": len(occupants),
        "students": [
            {
                "id": student.id,
                "name": student.name,
                "student_id": student.student_id
            }
            for student in occupants
        ]
    }

@router.post("/assign", response_model=RoomResponse)
async def assign_room(
    assignment: RoomAssignmentRequest,
    current_admin: Student = Depends(get_current_admin),
    db: Session = Depends(get_db)
):
    """
    分配宿舍
    
    参数:
    - student_id: 学生ID
    - room_id: 房间ID
    """
    student = db.query(Student).get(assignment.student_id)
    room = db.query(Room).get(assignment.room_id)
    
    if not student or not room:
        raise HTTPException(status_code=404, detail="学生或宿舍不存在")
        
    dormitory_service = DormitoryAssignmentService(db)
    dormitory_service.assign_room(student, room)
    return room

@router.post("/assign/group", response_model=RoomResponse)
async def assign_group_to_room(
    student_ids: List[int],
    room_id: int,
    current_admin: Student = Depends(get_current_admin),
    db: Session = Depends(get_db)
):
    """
    将一组学生分配到同一个宿舍
    
    参数:
    - student_ids: 学生ID列表
    - room_id: 目标房间ID
    """
    students = db.query(Student).filter(Student.id.in_(student_ids)).all()
    room = db.query(Room).get(room_id)
    
    if not room:
        raise HTTPException(status_code=404, detail="房间不存在")
    if len(students) != len(student_ids):
        raise HTTPException(status_code=404, detail="部分学生不存在")
        
    dormitory_service = DormitoryAssignmentService(db)
    dormitory_service.assign_group_to_room(students, room)
    return room

@router.post("/remove/{student_id}")
async def remove_from_room(
    student_id: int,
    current_admin: Student = Depends(get_current_admin),
    db: Session = Depends(get_db)
):
    """
    将学生从当前宿舍中移除
    
    参数:
    - student_id: 学生ID
    """
    student = db.query(Student).get(student_id)
    if not student:
        raise HTTPException(status_code=404, detail="学生不存在")
        
    dormitory_service = DormitoryAssignmentService(db)
    dormitory_service.remove_from_room(student)
    return {"status": "success"}

@router.post("/swap-request", response_model=SwapRequestResponse)
async def create_swap_request(
    swap_request: SwapRequestCreate,
    current_user: Student = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    创建宿舍调换申请
    
    参数:
    - target_student_id: 目标学生ID
    """
    dormitory_service = DormitoryAssignmentService(db)
    return dormitory_service.create_swap_request(
        requester_id=current_user.id,
        target_id=swap_request.target_student_id
    )

@router.post("/swap-request/{request_id}/process")
async def process_swap_request(
    request_id: int,
    approve: bool,
    current_admin: Student = Depends(get_current_admin),
    db: Session = Depends(get_db)
):
    """
    处理宿舍调换申请
    
    参数:
    - request_id: 申请ID
    - approve: 是否批准
    """
    dormitory_service = DormitoryAssignmentService(db)
    dormitory_service.process_swap_request(request_id, current_admin.id, approve)
    return {"status": "success"}

@router.post("/optimize")
async def optimize_assignments(
    current_admin: Student = Depends(get_current_admin),
    db: Session = Depends(get_db)
):
    """
    优化宿舍分配
    
    说明：
    - 自动为未分配宿舍的学生找到最优的宿舍组合
    - 考虑性别、年级等因素
    - 尽可能将互选的学生安排在一起
    """
    dormitory_service = DormitoryAssignmentService(db)
    assignments = dormitory_service.optimize_room_assignments()
    return {
        "status": "success",
        "assignments": [
            {
                "student_id": student.id,
                "student_name": student.name,
                "room_id": room.id,
                "room_number": room.room_number
            }
            for student, room in assignments
        ],
        "total_count": len(assignments)
    } 